package cn.tedu.zx.ums.service.impl;

import cn.tedu.zx.common.exception.ServiceException;
import cn.tedu.zx.common.restful.JsonPage;
import cn.tedu.zx.common.restful.ResponseCode;
import cn.tedu.zx.order.service.BookingService;
import cn.tedu.zx.pojo.order.entity.Booking;
import cn.tedu.zx.pojo.users.entity.User;
import cn.tedu.zx.pojo.users.param.*;
import cn.tedu.zx.pojo.users.vo.*;
import cn.tedu.zx.ums.mapper.UserMapper;
import cn.tedu.zx.ums.service.IUserRegService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;

@Service
@Slf4j
@EnableRedisRepositories
public class UserRegServiceImpl implements IUserRegService {
    //在此
    @Autowired
    UserMapper userMapper;
    @DubboReference
    private BookingService bookingService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    private RedisTemplate<String,Serializable> redisTemplate;

    @Override
    public void addNew(UserRegAddNewParam userRegAddNewParam) {
        System.out.println("UserMapper如果出错，无法导入文件，删除mapper文件夹里的UserMapper，重新写");
        log.debug("开始处理【用户注册】的业务，参数：{}", userRegAddNewParam);
        //检查用户名称是否被占用，如果被占用，则抛出异常
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userRegAddNewParam.getUsername());//name=‘参数中的用户名称’
        int countByName = userMapper.selectCount(queryWrapper);
        log.debug("根据用户名统计匹配的用户数量，结果：{}", countByName);
        if (countByName > 0) {
            String message = "用户注册失败，用户名称已经被占用！";
            log.warn(message);
            throw new RuntimeException();
        }
        //将用户数据写入到数据库中
        Random random = new Random();
        User user = new User();
        BeanUtils.copyProperties(userRegAddNewParam, user);
        user.setNickname(String.valueOf(random.nextInt(1000000000)));
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setCreated(LocalDateTime.now());
        userMapper.insert(user);
        log.debug("将新的用户数据插入到数据库，完成！");
    }

    public UserRemPasswordVO getUserRemPassword(String phone){
        UserRemPasswordVO result = userMapper.getUserRemPassword(phone);
        if (result == null){
            String message = "信息有误，请输入正确的手机号码";
            log.warn(message);
            throw new RuntimeException();
        }

        Random random = new Random();
        String code= String.valueOf(random.nextInt(999999));
        result.setRandomCode(code);
        //将username和phone为key，random为value，存入redis
        ValueOperations<String, Serializable> ops = redisTemplate.opsForValue();
        String s = result.getUsername() + "-" + result.getPhone();
        ops.set(s,result.getRandomCode() );
        return result;
    }

    @Override
    public UpdatePasswordByEmailVO getUserPasswordByEmail(String email) {
        UpdatePasswordByEmailVO result = userMapper.getUpdatePasswordByEmail(email);
        if (result == null){
            String message = "信息有误，请输入正确的邮箱号码";
            log.warn(message);
            throw new RuntimeException();
        }

        Random random = new Random();
        String code= String.valueOf(random.nextInt(999999));
        result.setRandomCode(code);
        //将username和email为key，random为value，存入redis
        ValueOperations<String, Serializable> ops = redisTemplate.opsForValue();
        String s = result.getUsername() + "-" + result.getEmail();
        ops.set(s,result.getRandomCode() );
        return result;
    }

    //将修改后的密码加密并存入用户信息
    public void updateUserRemPassword(UserRemPasswordParam userRemPasswordParam){
        //根据用户输入的信息，获取redis中的random
        String phone = "[0-9]*";
        boolean match = userRemPasswordParam.getPhone().matches(phone);
        ValueOperations<String, Serializable> ops = redisTemplate.opsForValue();
        if (match){
            String key = userRemPasswordParam.getUsername()+"-"+userRemPasswordParam.getPhone();
            Serializable randomCode = ops.get(key);
            log.info(randomCode+"");
            log.debug("{}",userRemPasswordParam);
            if (!randomCode.equals(userRemPasswordParam.getRandomCode())){
                String message = "验证码错误，请重新输入";
                log.warn(message);
                throw new RuntimeException();
            }
        }else {
            String key = userRemPasswordParam.getUsername()+"-"+userRemPasswordParam.getEmail();
            Serializable randomCode = ops.get(key);
            log.info(randomCode+"");
            log.debug("{}",userRemPasswordParam);
            if (!randomCode.equals(userRemPasswordParam.getRandomCode())){
                String message = "验证码错误，请重新输入";
                log.warn(message);
                throw new RuntimeException();
            }
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        String encode = passwordEncoder.encode(userRemPasswordParam.getNewPassword());
        queryWrapper.eq("username",userRemPasswordParam.getUsername())
                .eq("password",encode);
        userMapper.updatePassword(encode,userRemPasswordParam.getUsername(),userRemPasswordParam.getPhone());
        log.debug("将新的用户数据插入到数据库，完成！");
    }

    public void updateInfoById(Long id, UserUpdateInfoParam userUpdateInfoParam) {
        log.debug("开始处理【修改用户详情】的业务，参数：{}", userUpdateInfoParam);
        //判断是否存在该用户名
        {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("password", userUpdateInfoParam.getPassword());
            int countById = userMapper.selectCount(queryWrapper);
            log.debug("根据用户密码统计匹配的用户数量，结果：{}", userUpdateInfoParam.getPassword());
            if (countById == 0) {
                String message = "修改用户详情失败，用户密码错误！";
                log.warn(message);
                throw new ServiceException(ResponseCode.NOT_FOUND, message);
            }
        }
        //判断原密码是否对应
        {
            String oldPassword = userMapper.getOldPassword(id);

            log.info(oldPassword+"");
            boolean matches = passwordEncoder.matches(userUpdateInfoParam.getPassword(),oldPassword);
            log.debug("根据用户ID统计匹配的用户数量，结果：{}", matches);
            if (!matches) {
                String message = "修改用户详情失败，密码错误！";
                log.warn(message);
                throw new ServiceException(ResponseCode.NOT_FOUND, message);
            }
        }

        // 执行修改
        User user = new User();
        BeanUtils.copyProperties(userUpdateInfoParam, user);
        user.setPassword(passwordEncoder.encode(userUpdateInfoParam.getNewPassword()));
        user.setId(id);
        int rows = userMapper.updateById(user);
        if (rows != 1) {
            String message = "修改用户详情失败，服务器忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ResponseCode.INTERNAL_SERVER_ERROR, message);
        }
        log.debug("将新的用户数据更新入到数据库，完成！");
    }

    @Override
    public void updateIsEnable(Long id, Integer isEnable) {
        log.debug("开始处理【修改is_enable】的业务，参数：{}，{}", id, isEnable);
        User user = new User();
        user.setId(id);
        user.setIsEnable(isEnable);
        user.setUpdated(LocalDateTime.now());
        int countByUpdate = userMapper.updateById(user);
        if (countByUpdate != 1) {
            String message = "用户变更启用值失败，数据库方面出现问题";
            log.warn(message);
            throw new ServiceException(ResponseCode.ERR_UPDATE, message);
        }
    }

    @Override
    public void deleteById(Long id) {
        int countByDelete = userMapper.deleteById(id);
        if (countByDelete != 1) {
            String message = "用户删除失败，数据库方面出现问题（用户不存在）";
            log.warn(message);
            throw new ServiceException(ResponseCode.ERR_DELETE, message);
        }

//        QueryWrapper<Booking> queryWrapper = new QueryWrapper();
//        queryWrapper.eq("user_id",id);
//        int countByOrderId=bookingService.listByUserId(id);
//        log.debug("根据订单ID统计匹配的订单数量，结果：{}", countByOrderId);
//        if (countByOrderId>0){
//            String message="删除用户失败，仍有订单关联到此用户！";
//            log.warn(message);
//            throw new ServiceException(ResponseCode.ERR_DELETE,message);
//        }
    }

    @Override
    public void updateDataById(UserUpdateDataParam userUpdateDataParam) {
        {
            QueryWrapper<User> queryPhone = new QueryWrapper<>();
            queryPhone.eq("phone",userUpdateDataParam.getPhone()).ne("id",userUpdateDataParam.getId());
            int countPhone = userMapper.selectCount(queryPhone);
            if (countPhone>=1){
                String message = "该电话号码已绑定用户";
                log.warn(message);
                throw new ServiceException(ResponseCode.ERR_UPDATE, message);
            }
        }
        User user = new User();
        BeanUtils.copyProperties(userUpdateDataParam, user);
        user.setUpdated(LocalDateTime.now());
        int countByUpdate = userMapper.updateById(user);
        if (countByUpdate != 1) {
            String message = "用户数据修改失败，数据库方面出现问题";
            log.warn(message);
            throw new ServiceException(ResponseCode.ERR_UPDATE, message);
        }
    }

    @Override
    public void updateAccountById(UserUpdateAccountParam userUpdateAccountParam) {
        User user = new User();
        BeanUtils.copyProperties(userUpdateAccountParam, user);
        user.setUpdated(LocalDateTime.now());
        user.setPassword(passwordEncoder.encode(userUpdateAccountParam.getPassword()));
        int countByUpdate = userMapper.updateById(user);
        if (countByUpdate != 1) {
            String message = "用户数据修改失败，数据库方面出现问题";
            log.warn(message);
            throw new ServiceException(ResponseCode.ERR_UPDATE, message);
        }
    }

    public UserStandardVO getStandardById(Long id) {
        log.debug("开始处理【根据ID查询用户详情】的业务，参数：{}", id);
        //检查相册名称是否被占用，如果被占用，则抛出异常
        UserStandardVO queryResult = userMapper.getStandardById(id);
        if (queryResult == null) {
            String message = "查询用户详情失败，用户数据不存在！";
            log.warn(message);
            throw new ServiceException(ResponseCode.NOT_FOUND, message);
        }
        return queryResult;
    }

    public JsonPage<UserListItemVO> list(Integer pageNum) {
        Integer pageSize = 5;
        return list(pageNum, pageSize);
    }

    public JsonPage<UserListItemVO> list(Integer pageNum, Integer pageSize) {
        log.debug("开始处理【查询相册列表】的业务，页码：{}，每页记录数：{}", pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        List<UserListItemVO> list = userMapper.list();
        PageInfo<UserListItemVO> pageInfo = new PageInfo<>(list);
        JsonPage<UserListItemVO> pageData = JsonPage.restPage(pageInfo);
        log.debug("查询完成，即将返回：{}", pageData);
        return pageData;
    }

    @Override
    public UserData getUserData(String username) {
        UserData userData = userMapper.getUserData(username);
        return userData;
    }
}
